package com.parsifal.server;

import android.content.Context;
import android.graphics.Bitmap;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;

import com.google.gson.Gson;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.parsifal.server.bean.ServerConfig;
import com.parsifal.server.callback.PortAllocatedCallback;
import com.parsifal.server.callback.SocketStateCallback;
import com.parsifal.server.socket.Server;

import java.util.HashMap;
import java.util.Map;

public class ServerActivity extends AppCompatActivity {

    private static final String TAG = ServerActivity.class.getSimpleName();

    private ListView mListView = null;

    private ImageView mImageView = null;

    private ServerAdapter mAdapter = null;

    private Server mServer = null;

    private Handler mHandler = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mHandler = new Handler();
        mListView = (ListView) findViewById(R.id.lv_content);
        mImageView = (ImageView) findViewById(R.id.img_qr);
        mAdapter = new ServerAdapter(this);
        mListView.setAdapter(mAdapter);

        mServer = new Server();
        mServer.setOnPortAllocatedListener(new PortAllocatedCallback() {
            @Override
            public void onAllocated(int port) {
                Log.e(TAG, "onPortAllocated " + port);
                String ip = getIP();
                Log.e(TAG, "ip " + ip);
                Log.e(TAG, "port " + port);
                ServerConfig serverConfig = new ServerConfig(port, ip);
                final Bitmap bitmap = generateBitmap(new Gson().toJson(serverConfig), 640, 640);
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mImageView.setImageBitmap(bitmap);
                    }
                });
            }
        });
        mServer.setSocketStateCallback(new SocketStateCallback() {
            @Override
            public void onConnected() {
                Log.e(TAG, "onConnected");
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mImageView.setVisibility(View.INVISIBLE);
                    }
                });
            }

            @Override
            public void onDisconnected() {
                Log.e(TAG, "onDisconnected");
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mImageView.setVisibility(View.VISIBLE);
                    }
                });
            }

            @Override
            public void onReceive(final String msg) {
                Log.e(TAG, "Send " + msg);
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mAdapter.addClientMessage(msg);
                        mListView.setSelection(mAdapter.getCount() - 1);
                    }
                });
            }

            @Override
            public void onSend(final String msg) {
                Log.e(TAG, "Send " + msg);
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        mAdapter.addServerMessage(msg);
                        mListView.setSelection(mAdapter.getCount() - 1);
                    }
                });
            }
        });
        mServer.listen();
    }

    private Bitmap generateBitmap(String content, int width, int height) {
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        Map<EncodeHintType, String> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        try {
            BitMatrix encode = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
            int[] pixels = new int[width * height];
            for (int i = 0; i < height; i++) {
                for (int j = 0; j < width; j++) {
                    if (encode.get(j, i)) {
                        pixels[i * width + j] = 0x00000000;
                    } else {
                        pixels[i * width + j] = 0xffffffff;
                    }
                }
            }
            return Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.RGB_565);
        } catch (WriterException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String getIP() {
        WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (!wifiManager.isWifiEnabled()) {
            wifiManager.setWifiEnabled(true);
        }
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        int ipAddress = wifiInfo.getIpAddress();
        return intToIp(ipAddress);
    }

    private String intToIp(int i) {
        return (i & 0xFF) + "." +
                ((i >> 8) & 0xFF) + "." +
                ((i >> 16) & 0xFF) + "." +
                (i >> 24 & 0xFF);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mServer.stopServer();
    }
}
